import { Injectable, Inject } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { AuthGuard } from '@nestjs/passport';

import {
  Controller,
  Get,
  Req,
  Post,
  HttpCode,
  Header,
  Param,
  Query,
  UseGuards,
  Res,
} from '@nestjs/common';
import { Observable, of } from 'rxjs';
import { User } from '../entities/user.entity';
import { Code } from '../entities/code.entity';
const moment = require('moment');
const _ = require('lodash');

import { createConnection } from 'typeorm';
import { Token } from '../entities/token.entity';

@Controller('user')
export class UserController {
  constructor(
    @InjectRepository(User)
    private readonly userRepository: Repository<User>,
    @InjectRepository(Code)
    private readonly codeRepository: Repository<Code>,
    @InjectRepository(Token)
    private readonly tokenRepository: Repository<Token>,
  ) {}

  @Get('select')
  async select(@Param() params) {
    const user = await this.userRepository.findOne({ id: '-1' });
    // const r = await this.userRepository.save(user);
    return Object.prototype.toString.call(user);
  }

  @Get('findUser')
  @UseGuards(AuthGuard())
  findUser(@Param() params): Observable<any> {
    return of({});
  }

  @Get('hasUser')
  async hasUser(@Param() params, @Req() req, @Res() res) {
    const { username } = req.query;
    const ret = await this.userRepository.findOne({ email: username });
    if (!!ret) {
      res.json({
        code: 200,
        data: true,
        msg: 'success',
      });
    } else {
      res.json({
        code: 200,
        data: false,
        msg: 'success',
      });
    }
  }

  @Post('/add')
  add() {
    return 'This action adds a new cat';
  }

  /**
   *  用户不存在 则 添加用户，
   *  存在 则 查找code
   *  存在code 则 核对 code，否则 返回错误
   *  正确 则 注册成功
   *  错误 则 注册失败
   *
   * @param req
   * @param res
   */
  @Post('enroll')
  async enroll(@Req() req, @Res() res) {
    const { code, password, username, verify } = req.body;
    const user = await this.userRepository.findOne({ email: username });
    let modelUser: any = undefined;
    if (!!user) {
      modelUser = user;
    }
    const form: any = {
      username: {
        valid: true,
        // 用户名不存在
        none: {
          valid: true,
        },
      },
      // password: {
      //   valid: true,
      //   // 密码是否匹配
      //   eq: {
      //     valid: true,
      //   },
      // },
      code: {
        valid: true,
        // 密码是否匹配
        eq: {
          valid: true,
        },
      },
      verify: {
        valid: true,
        // 密码是否匹配
        eq: {
          valid: true,
        },
      },
      valid: false,
    };
    const validateForm = async () => {
      // 用户是否不存在
      form.username.none.valid = !user;

      const codeRet = await this.codeRepository.findOne({ username });

      // 验证码是否匹配
      form.code.eq.valid = codeRet.code === code;

      //图形验证码是否匹配

      form.verify.eq.valid = true; // 暂时写死，后续需要调用接口验证

      let valid = true;

      _.forEach(form, (item: any, key: string) => {
        if (item && item.hasOwnProperty('valid')) {
          let itemValid = true;
          _.forEach(item, (it: any, k: string) => {
            if (it && it.hasOwnProperty('valid')) {
              valid = valid && it.valid;
              itemValid = itemValid && it.valid;
            }
          });
          form[key].valid = itemValid;
        }
      });

      form.valid = valid;

      return form;
    };

    await validateForm();

    if (form.valid) {
      try {
        const userM = new User();
        userM.email = username;
        userM.password = password;
        await this.userRepository.save(userM);
        res.json({
          code: 200,
          data: undefined,
          msg: 'success',
        });
      } catch (e) {
        res.json({
          code: 7001,
          data: undefined,
          msg: 'do error',
        });
        return;
      }
      return;
    }

    if (!form.verify.eq.valid) {
      res.json({
        msg: '图形验证码不正确',
        data: undefined,
        code: 'user_neq_verify',
      });
      return;
    }
    if (!form.username.none.valid) {
      res.json({
        msg: '用户名已存在',
        data: undefined,
        code: 'user_username_has_exsits',
      });
      return;
    }

    if (!form.code.eq.valid) {
      res.json({
        msg: '验证码不正确',
        data: undefined,
        code: 'user_neq_code',
      });
      return;
    }

    return;
  }

  @Post('login')
  async login(@Req() req, @Res() res): Promise<User[]> {
    const { code, password, username, verify } = req.body;
    const user = await this.userRepository.findOne({ email: username });
    let modelUser: any = undefined;
    if (!!user) {
      modelUser = user;
    }
    const form: any = {
      username: {
        valid: true,
        has: {
          valid: true,
        },
      },
      password: {
        valid: true,
        // 密码是否匹配
        eq: {
          valid: true,
        },
      },
      code: {
        valid: true,
        // 密码是否匹配
        eq: {
          valid: true,
        },
      },
      verify: {
        valid: true,
        eq: {
          valid: true,
        },
      },
      valid: false,
    };
    const validateForm = async () => {
      // 用户是否存在
      form.username.has.valid = !!user;

      // 密码是否匹配
      if (!!modelUser) {
        form.password.eq.valid = modelUser.password === password;
      }

      const codeRet = await this.codeRepository.findOne({ username });

      // 短信或手机是否匹配
      form.code.eq.valid = codeRet.code === code;

      //图形验证码是否匹配

      form.verify.eq.valid = true; // 暂时写死

      let valid = true;

      _.forEach(form, (item: any, key: string) => {
        if (item && item.hasOwnProperty('valid')) {
          let itemValid = true;
          _.forEach(item, (it: any, k: string) => {
            if (it && it.hasOwnProperty('valid')) {
              valid = valid && it.valid;
              itemValid = itemValid && it.valid;
            }
          });
          form[key].valid = itemValid;
        }
      });

      form.valid = valid;

      return form;
    };

    await validateForm();

    if (form.valid) {
      const tokenM = new Token();
      tokenM.pid = user.id;
      tokenM.createTime = moment().unix();
      tokenM.expireTime = moment()
        .add(30, 's')
        .unix();

      await this.tokenRepository.save(tokenM);

      res.json({
        code: 200,
        data: modelUser,
        msg: 'success',
      });
      return;
    }
    if (!form.username.has.valid) {
      res.json({
        code: 200,
        data: undefined,
        msg: 'success',
      });
      return;
    }
    if (!form.password.eq.valid) {
      res.json({
        code: 5008,
        data: undefined,
        msg: '密码不正确',
      });
      return;
    }
    if (!form.code.eq.valid) {
      res.json({
        msg: '验证码不正确',
        data: undefined,
        code: 5009,
      });
      return;
    }
  }

  @Get('forgot')
  async forgot(): Promise<User[]> {
    const user = new User();
    await this.userRepository.save(user);
    return await this.userRepository.find();
  }
}
